#ifdef WX_PRECOMP
#include "wx_pch.h"
#else
#include <wx/wx.h>
#endif //WX_PRECOMP

#include "component_info_const.h"
#include <map>

namespace
{
  struct DescriptionItem
  {
    ComponentType Type;
    UnitCalculator::FieldEnum Field;
  };

  typedef std::map<ComponentType, Dictionary::ComponentDescriptionFieldVector> ComponentDescriptionMapType;

  const DescriptionItem DescriptionItemArray[] =
  {
    { TYPE_CHASSIS, UnitCalculator::FieldCostMain },
    { TYPE_CHASSIS, UnitCalculator::FieldCostSecond },
    { TYPE_CHASSIS, UnitCalculator::FieldCostMoney },
    { TYPE_CHASSIS, UnitCalculator::FieldSupportMain },
    { TYPE_CHASSIS, UnitCalculator::FieldSupportSecond },
    { TYPE_CHASSIS, UnitCalculator::FieldHitPoints },
    { TYPE_CHASSIS, UnitCalculator::FieldLaserDefence },
    { TYPE_CHASSIS, UnitCalculator::FieldRocketDefence },
    { TYPE_CHASSIS, UnitCalculator::FieldWeight },
    { TYPE_CHASSIS, UnitCalculator::FieldMaxWeight },

    { TYPE_LASER_WEAPON, UnitCalculator::FieldCostMain },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldCostSecond },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldCostMoney },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldSupportMain },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldSupportSecond },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldLaserAttack },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldLaserDamage },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldHitPoints },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldWeight },

    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldCostMain },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldCostSecond },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldCostMoney },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldSupportMain },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldSupportSecond },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldRocketAttack },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldRocketDamage },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldHitPoints },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldWeight },

    { TYPE_DEFENCE, UnitCalculator::FieldCostMain },
    { TYPE_DEFENCE, UnitCalculator::FieldCostSecond },
    { TYPE_DEFENCE, UnitCalculator::FieldCostMoney },
    { TYPE_DEFENCE, UnitCalculator::FieldSupportMain },
    { TYPE_DEFENCE, UnitCalculator::FieldSupportSecond },
    { TYPE_DEFENCE, UnitCalculator::FieldHitPoints },
    { TYPE_DEFENCE, UnitCalculator::FieldLaserDefence },
    { TYPE_DEFENCE, UnitCalculator::FieldRocketDefence },
    { TYPE_DEFENCE, UnitCalculator::FieldWeight },

    { TYPE_DISCOVERY, UnitCalculator::FieldCostMain },
    { TYPE_DISCOVERY, UnitCalculator::FieldCostSecond },
    { TYPE_DISCOVERY, UnitCalculator::FieldCostMoney },
    { TYPE_DISCOVERY, UnitCalculator::FieldSupportMain },
    { TYPE_DISCOVERY, UnitCalculator::FieldSupportSecond },
    { TYPE_DISCOVERY, UnitCalculator::FieldDetectRange },
    { TYPE_DISCOVERY, UnitCalculator::FieldHitPoints },
    { TYPE_DISCOVERY, UnitCalculator::FieldScanStrength },
    { TYPE_DISCOVERY, UnitCalculator::FieldStealthLevel },
    { TYPE_DISCOVERY, UnitCalculator::FieldWeight },

    { TYPE_TRANSPORT, UnitCalculator::FieldCostMain },
    { TYPE_TRANSPORT, UnitCalculator::FieldCostSecond },
    { TYPE_TRANSPORT, UnitCalculator::FieldCostMoney },
    { TYPE_TRANSPORT, UnitCalculator::FieldSupportMain },
    { TYPE_TRANSPORT, UnitCalculator::FieldSupportSecond },
    { TYPE_TRANSPORT, UnitCalculator::FieldHitPoints },
    { TYPE_TRANSPORT, UnitCalculator::FieldWeight },

    { TYPE_MOTIVATOR, UnitCalculator::FieldCostMain },
    { TYPE_MOTIVATOR, UnitCalculator::FieldCostSecond },
    { TYPE_MOTIVATOR, UnitCalculator::FieldCostMoney },
    { TYPE_MOTIVATOR, UnitCalculator::FieldSupportMain },
    { TYPE_MOTIVATOR, UnitCalculator::FieldSupportSecond },
    { TYPE_MOTIVATOR, UnitCalculator::FieldHitPoints },
    { TYPE_MOTIVATOR, UnitCalculator::FieldMotivator },
    { TYPE_MOTIVATOR, UnitCalculator::FieldFuel },
    { TYPE_MOTIVATOR, UnitCalculator::FieldWeight },

    { TYPE_UNKNOW, UnitCalculator::FieldCostMain },
  };

  const DescriptionItem DescriptionSubItemArray[] =
  {
    { TYPE_CHASSIS, UnitCalculator::FieldCostPeople },
    { TYPE_CHASSIS, UnitCalculator::FieldBuildSpeed },
    { TYPE_CHASSIS, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_LASER_WEAPON, UnitCalculator::FieldCostPeople },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldBuildSpeed },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldLaserNumber },
    { TYPE_LASER_WEAPON, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldCostPeople },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldBuildSpeed },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldRocketNumber },
    { TYPE_ROCKET_WEAPON, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_DEFENCE, UnitCalculator::FieldCostPeople },
    { TYPE_DEFENCE, UnitCalculator::FieldBuildSpeed },
    { TYPE_DEFENCE, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_DISCOVERY, UnitCalculator::FieldCostPeople },
    { TYPE_DISCOVERY, UnitCalculator::FieldBuildSpeed },
    { TYPE_DISCOVERY, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_TRANSPORT, UnitCalculator::FieldCostPeople },
    { TYPE_TRANSPORT, UnitCalculator::FieldBuildSpeed },
    { TYPE_TRANSPORT, UnitCalculator::FieldTransportCapacity },
    { TYPE_TRANSPORT, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_MOTIVATOR, UnitCalculator::FieldCostPeople },
    { TYPE_MOTIVATOR, UnitCalculator::FieldBuildSpeed },
    { TYPE_MOTIVATOR, UnitCalculator::FieldHasMilitaryParts },

    { TYPE_UNKNOW, UnitCalculator::FieldCostMain },
  };


  const ComponentDescriptionMapType CreateMap(const DescriptionItem* arr, size_t size)
  {
    ComponentDescriptionMapType result;
    for (size_t i = 0; i < size; ++i)
    {
      result[arr[i].Type].push_back(arr[i].Field);
    }
    return result;
  }

  const Dictionary::ComponentDescriptionFieldVector& FindItem(const ComponentDescriptionMapType& descriptionInfo, const ComponentType& type)
  {
    ComponentDescriptionMapType::const_iterator i = descriptionInfo.find(type);
    if (i != descriptionInfo.end())
    {
      return (*i).second;
    }
    i = descriptionInfo.find(TYPE_UNKNOW);
    return (*i).second;
  }

} // end of anonymous namespace

namespace Dictionary
{

  const ComponentDescriptionFieldVector& GetVariableComponentDescriptionField(const ComponentType& type)
  {
    static const ComponentDescriptionMapType& descriptionInfo =
      CreateMap(DescriptionItemArray, sizeof(DescriptionItemArray) / sizeof(DescriptionItemArray[0]));
    return FindItem(descriptionInfo, type);
  }

  const ComponentDescriptionFieldVector& GetConstComponentDescriptionField(const ComponentType& type)
  {
    static const ComponentDescriptionMapType& descriptionInfo =
      CreateMap(DescriptionSubItemArray, sizeof(DescriptionSubItemArray) / sizeof(DescriptionSubItemArray[0]));
    return FindItem(descriptionInfo, type);
  }

} // end of Dictionary namespace
